package com.zzf.concurrent.example.sync;

import com.zzf.concurrent.example.sync.bean.DeadLock;
import com.zzf.concurrent.example.sync.bean.OtherService;
import com.zzf.concurrent.example.util.TimeUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author GaoFeng2017
 * @date 2019/8/6 9:16
 */
@Slf4j
public class DeadLockExample {

    private static final Object LOCK_A = new Object();
    private static final Object LOCK_B = new Object();

    public static void main(String[] args) {
        multiLockObject();
    }

    private static void simpleDeadLock() {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    synchronized (LOCK_A) {
                        log.info("{} -> get Lock A", this.getName());
                        TimeUtil.sleep(1);
                        synchronized (LOCK_B) {
                            log.info("{} -> get Lock B", this.getName());
                            TimeUtil.sleep(1);
                        }
                    }
                }
            }
        };

        Thread t2 = new Thread() {
            @Override
            public void run() {
                while (true) {
                    synchronized (LOCK_B) {
                        log.info("{} -> get Lock B", this.getName());
                        TimeUtil.sleep(1);
                        synchronized (LOCK_A) {
                            log.info("{} -> get Lock A", this.getName());
                            TimeUtil.sleep(1);
                        }
                    }
                }
            }
        };

        t1.start();
        t2.start();
    }

    private static void multiLockObject() {

        DeadLock deadLock = new DeadLock();
        OtherService otherService = new OtherService(deadLock);
        deadLock.setOtherService(otherService);

        Thread t1 = new Thread(deadLock);
        Thread t2 = new Thread(otherService);

        t1.start();
        t2.start();

    }
}
